Table of contents

License and Action

Generic Actions
        act_unlock: Activate License
        act_lock: Deactivate License
        act_clean: Clean up License Storage
        act_fix: Error Fix
        act_oneShot: License One-shot Usage
        act_shelfTime: License Best Before Time
        act_setVar: set value of a user defined variable
        act_revoke: Online License Transfer
        act_disableFingerprintChecking: Disable Fingerprint Checking
        act_disableClockRollbackChecking: Disable Clock Rollback Checking
Trial License Models
        act_resetAllExpiration: Reset Expire Settings
        exitAppOnExpire: What to do when app expires?
        Expire by Access Times
                ACT_ADD_ACCESSTIME
                ACT_SET_ACCESSTIME
        Expire by Hard Date
                ACT_SET_STARTDATE
                ACT_SET_ENDDATE
        Expire by Period
                ACT_SET_EXPIRE_PERIOD
                ACT_ADD_EXPIRE_PERIOD
        Expire by Duration
                ACT_SET_EXPIRE_DURATION
                ACT_ADD_EXPIRE_DURATION
        Expire by Session Time
                ACT_SET_SESSION_TIME
Non-Trial License Model
        Always Run
        Always Lock

Generic Actions

In SoftwareShield, action is the official way to modify the license status. In this chapter we will discuss in details all generic actions, which can be applied to any license models.

Action Action ID Parameters One-Shot
act_unlock ACT_UNLOCK (1) N/A No
act_lock ACT_LOCK (2) N/A No
act_clean ACT_CLEAN (11) "endDate" No
act_fix ACT_FIX (19) N/A Yes
act_oneShot ACT_ONE_SHOT (17) N/A Yes
act_shelfTime ACT_SHELFTIME (18) "endDate" No
act_setVar ACT_SET_VAR (21) "name", "value" No
act_disable-FingerprintChecking ACT_DISABLE_FINGERPRINTCHECKING (7) N/A Yes
act_disableClockRollbackChecking act_disableClockRollbackChecking N/A No

act_unlock: Activate License

Sets a licence’s lock state to STATAUS_UNLOCKED so the target licence’s internal logic is ignored and the license protected entity can always be accessed. SoftwareShield uses this action to activate an entity or the whole application. act_unlock has no action parameter and is a multi-use action.

act_lock: Deactivate License

Sets a licence’s lock state to STATAUS_LOCKED so the target licence’s internal logic is ignored and the license protected entity can not be accessed. SoftwareShield uses this action to deactivate an entity or the whole application.

act_lock has no action parameter and is a multi-use action.

When a license model expires, its state will also go to STATUS_LOCKED automatically.

If act_lock is applied before a license model expires, the current license parameters are frozen and not be used.

act_clean: Clean up License Storage

Clean up the local license storage as if the application was not installed before.

When QA testing a SoftwareShield protected application, you might want to erase all local license traces and restart a license testing again, in SoftwareShield IDE, you can do this by click the Cleanup button on the toolbar, or click the main menu item "Build => Cleanup".

After the application's license is cleaned, when next time the application is launched, the original license data (generated when building the application's license project in SoftwareShield IDE) is saved to local license storage, so everything will roll back to initial status.

Sometimes when a SoftwareShield proteced application has a license error, clean up license might be able to fix the problem; however, it is highly recommended to use act_fix instead of act_clean because after license clean up, the end user has to re-activate the application. In use scenario that there are multiple serial numbers to activate different app-modules, it might be difficult for end users to find and input all used serial numbers.

act_clean has a built-in parameter endDate which allows you to optionally specify an expire date of the hosting license code or SN ( refer act_shelfTime). By default, the parameter does not hold a valid date time, so there is no expiration date for this action; However, because this action resets the local license status to its initial state, most likely you do not allow the game player to do this multiple times for a trial license model, so you should set the endDate to an appropriate time to prohibit reuse of the the same clean code.

The reason why this action cannot be an one-shot action is that after the action is applied, the current license status is purged including the information of used license codes, so the use of clean action has to be restricted by a hard-coded shelf-time.

act_fix: Error Fix

When unexpected license error occurs to the SoftwareShield protected application at runtime, it might because:

  • Fingerprint Mismatch Hardware information modification detected.

  • License Data Corruption License data is corrupted and failed to open and decode.

  • Application Integrity Corrupted Application binary is patched in memory or the content of a supposed to be read-only files protected by integrity checking is modified.

  • Application Clock Roll-backed The local clock is modified intentionally to bypass expiry restriction.

The act_fix tries to detect and fix all of the above mentioned issues at runtime.

This is an one-shot action so the license code hosting act_fix can be used only once for a single machine.

Before SoftwareShield v5.3, the act_fix is named act_fpFix which can only fix fingerprint mismatch error.

act_oneShot: License One-shot Usage

A license code is one-shot if it embeds at least 1 \emph{one-shot} action. Similarly, A SN (Serial Number) is one-shot if the what-can-do actions associated with this SN has at least 1 one-shot action.

Basically act_oneShot is a do-nothing dummy action but its existence can assign the one-shot attribute to a license code or SN.

If you want to generate an one-shot license code, or you want to make sure the SN can only be used once at the same client side, you can manually add act_oneShot to the set of authorized actions. When the license code or serial number is being applied at the client side, the act_oneShot is detected and as a result the license code or serial number will be tagged as one-shot status, the next time when the user tries to input the license code or serial number again, they will be rejected at client side. For online activation, you can also enforce the limit by setting the serial number's maximum activations to 1.

If the license code already has an one-shot action (such as act_fix), there is no need to add act_oneShot again, it will make the license code longer;

act_shelfTime: License Best Before Time

Like act_oneShot, act_shelfTime is also a dummy action that does nothing to local license status, but it has a parameter named "endDate" that specifies a UTC (Coordinated Universal Time) time after which the license code embedding it expires.

If the license code is retrieved internally from a SN while online activating, and the license code has a best before date defined by an act_shelfTime action, the SoftwareShield will save the expiry date for this SN so that an expired SN will not invoke an online code exchange attempt at all.

act_oneShot and act_shelfTime can be used independently or combined together to restrict the usage of a license code or serial number.

act_setVar: set value of a user defined variable

act_setVar has two parameters: name} and value, all of them are of string type. This action can be used to change the value of user defined variable of any type.

act_revoke: Online License Transfer

act_revoke is to deactivate the local unlocked entities and decrease the consumed seat counter by 1 at server side.

After the license is revoked, the application cannot launch properly on this machine, but the customer can install and activate a new copy on another machine with the same SN due to the recollected seat.

There is no need to use this action directly, the SoftwareShield SDK has implemented API to support license transfer.

act_disableFingerprintChecking: Disable Fingerprint Checking

This action disables local fingerprint checking when node-locked application runs. It can be a temporary fix for a client machine having fingerprint mismatch issue.

Normally the act_fix can also fix the fingerprint mismatch issue in a different way: it re-trake a snapshot the current hardware informations to make sure the stored fingerprint matches the current hardware status, the fingerprint mismatch issue might occur again if the hardware makes another changes (depending on the fingerprint error tolerance value you set in the license project). act_disableFingerprintChecking fix the issue by completely disable fingerprint checking.

act_disableClockRollbackChecking: Disable Clock Rollback Checking

act_fix can fix rollback issue properly, however, for some machines due to the on-board battery low issue or , the local CMOS clock might lag behind / go forward hence when sync with the time server on Windows periodically, there will be clock jumping issue which can only be "fixed" by disable the clock rollback detection.

One interesting web site Test your Clock might give you the idea of the possibility distribution a machine can run slower or faster than the correct time.

If your license model is Expire By Period or Expire By Hard Date, which relies on precise clock before fully unlocked, then you must choose a reasonable rollback tolerance, if you are sure the customer is a valid customer who is having clock issue, then you can issue an serial number with act_disableClockRollbackChecking to completely disable the clock checking algorithm.

SoftwareShield has implemented some commonly used licensing logic units, you can use them directly or combine them as one composite license logic.

There are two categories of built-in license models:

Trial License Models

The license model with a trial limit. After the trial limit is expired, the protected entity will switch to Locked status,

The trial limit can be defined as maximum app launch times (Expire by Access Times), the maximum running time for each app launch(Expire by Session Time), cumulative trial duration (Expire by Duration) or non-cumulative trial period after first run (Expire By Period), or a hard coded expiration date (Expire By Hard Date).

act_resetAllExpiration: Reset Expire Settings

This is a common action supported by all trial license models.

If the trial period of your application has expired, and you want to give your potential customers another trial, you can create a serial number with this action to reset the trial period or duration so that they can restart the trial period again.

exitAppOnExpire: What to do when app expires?

This is a common license property for every trial license model types, which defines if the SoftwareShield kernel should force app terminating after the trial limit is exceeded at runtime.

By default its value is true, you can modify it in case you want to handle the license behavior in your own code when SDK integration.

Expire by Access Times

  • LicenseID gs.lm.expire.accessTime.1

  • Description The protected entity cannot be accessed after it has been accessed more than a maximum times

    For example, you can allow the application to launch in demo mode for maximum 8 times, or for Pay-Per-Usage price model, the customer can buy license that topping more access times (act_addAccessTime) before the application is locked.

  • Function

\displaystyle f(usedTimes, maxAccessTimes) = \begin{cases} true, & \text{if usedTimes} \le \text{maxAccessTimes} \\ false, & \text{otherwise} \end{cases}
  • Parameters
Name Type Default Description
usedTimes uint32 0 How many access times has been consumed
maxAccessTimes uint32 8 Maximum access times allowed
  • License Specific Actions

ACT_ADD_ACCESSTIME

Adds app trial access times to current value.

ACT_SET_ACCESSTIME

Sets new app trial access times.

Add Access Times Set Access Times
ActionID ACT_ADD_ACCESSTIME (100) ACT_SET_ACCESSTIME (101)
Parameters
  • Type: int32
  • Name: addedAccessTime
  • Default: 0
  • Type: int32
  • Name: newAccessTime
  • Default: 0
Description maxAccessTimes := maxAccessTimes + addedAccessTime maxAccessTimes := newAccessTime
  • Generic actions supported

    1. act_lock
    2. act_unlock
    3. act_resetAllExpiration: After the action is applied, the usedTimes is reset to 0.

Expire by Hard Date

  • LicenseID gs.lm.expire.hardDate.1

  • Description Protected entity can be accessed depending on the relationship between current time and the begin or end date.

    Depending on the license parameter settings, there are three use scenarios:

  1. Valid Within Range

License is valid during a specified time range. Using this license model, you can enforce that your product can only be used in a specified time range. For example, the customers can buy license allow them to use your service during 2013 and 2014, if they want to renew the service, they can buy another license to set the time range between 2014 and 2015.

  1. Expire After

License expires after an ending date. In supermarket, there is a \emph{Best Before Date} printed on the food package. You can also enforce that your service cannot be used after an expire date. You can also find similar \emph{Pay-As-You-Go} plan in mobile phone market, the customers buy pre-paid card from shop or web site, extending the expire date by topping more money to their account.

  1. Valid Since

License becomes valid since a starting date. You can use this model to allow end users download and pre-install application binaries, but the application won't fully work until a global launching date.

  • Function
\displaystyle f(t, t_b, t_e) = \begin{cases} true & \text{if } t_b \le t < t_e \text{ and both }t_b, t_e \text{ are defined ( valid between range [} t_b \text{, } t_e \text{))} \\ true & \text{if } t \le t_e \text{ and } t_b \text{ is disabled (expire after } t_e \text{)} \\ true & \text{if } t_b \le t \text{ and } t_e \text{ is disabled (valid since } t_b \text{)} \\ false & otherwise \end{cases}
  • Parameters

    The license model has five parameters, you can define a start point (timeBegin) and enable it (timeBeginEnabled), or define an end point (timeEnd) and enable it (timeEndEnabled), another important parameter rollbackTolerance controls how the clock roll-back detection works.

Name Type Default Description
timeBegin UTC time Not defined Start point of time range
timeEnd UTC time Not defined End point of time range
timeBeginEnabled bool false Enable the timeBegin
timeEndEnabled bool true Enable the timeEnd
rollbackTolerance int32 1800 (30 min) Maximum clock roll back period in seconds
  • License Specific Actions

ACT_SET_STARTDATE

Sets new start date.

ACT_SET_ENDDATE

Sets new end date.

Set Start Date Set End Date
ActionID ACT_SET_STARTDATE (102) ACT_SET_ENDDATE (103)
Parameters
  • Type: UTC Time
  • Name: startDate
  • Default: Not Defined
  • Type: UTC Time
  • Name: endDate
  • Default: Not Defined
Description timeBegin = action.startDate; timeBeginEnabled := false if action.startDate is not defined timeEnd := action.endDate; timeEndEnabled := false if action.endDate is not defined

If the action's parameter (startDate / endDate) is not defined (not holding a valid date time), then the corresponding license parameter (timeBeginEnabled / timeEndEnabled) is set to false to disable the old threshold value.

  • Generic actions supported
    • act_lock
    • act_unlock

Expire by Period

  • LicenseID gs.lm.expire.period.1
  • Description Protected entity expires after it has been accessed more than a pre-set time period

When the license is first accessed (usually when the application first launches and the Play button is pressed), the time is saved and the expiry date is also calculated by adding trial period (periodInSeconds) to the first access time.

Compared with Expire by Hard Date, the expire by period is similar to the Valid Within Range scenario, except that the start time point is from the moment license is first accessed.

  • Function
\displaystyle f(t, t_0, T) = \begin{cases} true & \text{if } t_0 \le t < t_0 + T \\ false & otherwise \end{cases}

\text{ Where } t_0 \text{ is the first time the protected entity was accessed, } T \text{ is time period allowed.}

The license model has three parameters, you can define a trial period periodInSeconds, and you can get the time the license is first accessed timeFirstAccess, another important parameter rollbackTolerance controls how the clock roll-back detection works.

Name Type Default Description
timeFirstAccess UTC time Not Defined Entity's first access time, only set when the entity is first accessed
periodInSeconds int32 28800 (8 hours) Time period allowed since first access
rollbackTolerance int32 1800 (30 min) Maximum clock roll back period in seconds
  • License Specific Actions

ACT_SET_EXPIRE_PERIOD

Sets new trial period.

ACT_ADD_EXPIRE_PERIOD

Extends trial period.

Set Expire Period Add Expire Period
ActionID ACT_SET_EXPIRE_PERIOD (105) ACT_ADD_EXPIRE_PERIOD (106)
Parameters
  • Type: int32
  • Name: newPeriodInSeconds
  • Default: 0
  • Type: int32
  • Name: addedPeriodInSeconds
  • Default: 0
Description Set the new trial period to newPeriodInSeconds, and the timeFirstAccess is set to current time Increase the new trial period by addedPeriodInSeconds, if the license is already expired, the trial period is extended so that there is still addedPeriodInSeconds time left to try. timeFirstAccess is not touched.
  • Generic actions supported
    1. act_lock
    2. act_unlock
    3. act_resetAllExpiration: After this action is applied, timeFirstAccess is reset to current time, so the trial period starts from current time point.

Expire by Duration

  • LicenseID gs.lm.expire.duration.1
  • Description License expires after the protected entity has been accessed cumulatively more than a pre-set time duration

The entity access time is calculated as following:

\displaystyle AccessTime = t_{end} - t_{start}

where t_{start} is the time the entity begins accessing (via SDK api gsEntityBeginAccess()), and t_{end} is the time the entity access ends (via SDK api gsEntityEndAccess()).

  • Function
\displaystyle f(t_i, T) = \begin{cases} true & \text{if } \displaystyle\sum_{i=1}^n t_i < T \\ false & otherwise \end{cases}

\text{ Where } t_i \text{ is the } i'th \text{ session time the protected entity was accessed, } T \text{ is time duration allowed.}

Compared with license model Expire by Period, the license won't expire until the trial time duration is actually used up accessing the protected entity, if you install a game and do not play it very open, the game protected by Expire by Duration won't expire, on the other hand, if the game is protected by Expire by Period, then it can expire even you just play it for one minute.

  • Parameters
Name Type Default Description
usedDurationInSeconds int32 0 Entity's cumulative accessed time
maxDurationInSeconds int32 28800 (8 hours) Maximum trial time duration allowed
  • License Specific Actions

ACT_SET_EXPIRE_DURATION

Sets new trial duration.

ACT_ADD_EXPIRE_DURATION

Extends trial duration.

Sets Expire Duration Extends Expire Duration
ActionID ACT_SET_EXPIRE_DURATION (107) ACT_ADD_EXPIRE_DURATION (108)
Parameters duration: int32, default 0 addedDuration: int32, default 0
Description maxDurationInSeconds = duration; usedDurationInSeconds = 0 maxDurationInSeconds += addedDuration
  • Generic actions supported
    1. act_lock
    2. act_unlock
    3. act_resetAllExpiration: After the action is applied, the usedDurationInSeconds is reset to 0.

Expire by Session Time

  • LicenseID gs.lm.expire.sessionTime.1

  • Description Protected entity expires after it has been accessed more than a pre-set session time.

    This license model allows an entity to be accessed in a limited time period. For example, your application protected by this license model, if not fully activated, can always launch (never expires) and keep playing in demo mode for 10 minutes each time.

  • Function
\displaystyle f(t,t_{start}, T) = \begin{cases} true & \text{ if } t_{start} \le t < t_{start} + T \\ false & otherwise \end{cases}

Where t_{start} is the start time the protected entity is accessed, T is maximum session time allowed.

  • Parameters
Name Type Default Description
sessionTimeUsed int32 0 Session time elapsed in seconds
maxSessionTime int32 180 (3 minutes) Maximum session time in seconds
  • License Specific Actions

ACT_SET_SESSION_TIME

Sets new app trial session time.

Sets Session Time
ActionID ACT_SET_SESSION_TIME (104)
Parameters newSessionTime: int32, default 180 (3 seconds)
Description maxSessionTime = newSessionTime;
  • Generic actions supported
    1. act_lock
    2. act_unlock

Non-Trial License Model

  1. License model is initially locked and do not allow any trial before fully activation (License Model Always Lock).
  2. License model is initially unlocked that can be locked later manually by serial numbers / license actions. (License Model Always Run).

Always Run

  • LicenseID gs.lm.alwaysRun.1
  • Description Protected entity can always be accessed.

This license model can be used to display some UI feedbacks (splash screen, up-sale screen, etc.) when the entity is to be accessed.

  • Function

    f(t) \equiv true;
  • Parameters None

  • License Specific Actions None

  • Generic actions supported

  1. act_lock
  2. act_unlock

Always Lock

  • LicenseID gs.lm.alwaysLock.1
  • Description Protected entity cannot be accessed until it is unlocked.

Use this license model to protect your application or application features that must be activated to use.

  • Function

    f(t) \equiv false;
  • Parameters None

  • License Specific Actions None

  • Generic actions supported

  1. act_lock
  2. act_unlock